/*
 * @Author: andy.dell andy@long.com
 * @Date: 2024-01-07 21:37:44
 * @LastEditors: andy.dell andy@long.com
 * @LastEditTime: 2024-01-09 20:18:16
 * @FilePath: \wasm\logic\snake\src\game\game.go
 * @Description:
 */
package service

import (
	"com.game.snake/consts"
	"com.game.snake/model"
	"com.game.snake/msg"
)

var _ IGame = (*Game)(nil)

type IGame interface {
	i()
	// 获取设置
	GetSetting() *model.Setting
	// 保存设置
	SaveSetting() bool
	// 刷新地图
	Refresh() msg.GameData
}
type Game struct {
	World     [][]*model.Cell // 地图 行索引、列索引 从0开始
	Snake     *model.Snake    // 蛇
	Score     int             // 得分
	Level     int             // 等级:长度/5，障碍物数=等级*3
	IsEated   bool            // 吃到了
	IsDead    bool            // 死了：要到自己、撞墙 或 撞到障碍物了
	Direction string          // 当前移动方向
	Set       *model.Setting  // 设置
	//
	lastFood *model.Pos // 上次吃到的食物，用来移除新增的蛇的位置

}

func (s *Game) i() {}

func (s *Game) resetStatus() *Game {
	s.IsEated = false
	return s
}

// 撞墙了
func (g *Game) IsHitWall(head model.Pos) bool {
	return head.Row >= g.Set.Height || head.Row < 0 || head.Col >= g.Set.Width || head.Col < 0
}

// 初始化地图
func initWorld(height, width int) [][]*model.Cell {
	world := make([][]*model.Cell, height)
	for i := 0; i < height; i++ {
		world[i] = make([]*model.Cell, width)
	}
	return world
}

// 创建游戏服务对象
func New(set *model.Setting) *Game {
	game := &Game{
		Score:     0,
		Level:     1,
		IsEated:   false,
		IsDead:    false,
		Direction: consts.DirectionDown,
		Set:       set,
	}
	game.World = initWorld(set.Height, set.Width)
	// 蛇
	game.Snake = model.NewSnake(set.Height, set.Width)
	// 把蛇占用的格子，放置到地图
	body := model.NewSnakeBody()
	for _, pos := range game.Snake.Dict {
		game.World[pos.Row][pos.Col] = body
	}
	// 除去占用的格子，随机格子放置障碍物，5%个障碍物 + 一个位置放食物
	max := set.Height * set.Width
	num := max*5/100 + 1
	game.randObject(1, num)
	return game
}
